#include <setjmp.h>
#include <SDL/SDL.h>

#include "common/common.h"
#include "common/global.h"
#include "common/net.h"
#include "common/Timer.h"
#include "client/client.h"
#include "server/server.h"

static void init_all(void)
{
	cmd_exec_file("landrc");
	init_client();
	init_server();
	init_net();
}

void com_quit(int error)
{
	release_client();
	release_server();
	release_net();
	exit(error);
}

static void poll_event(void);

int main(int argc, const char *argv[])
{
	init_all();

	extern jmp_buf abort_spot;
	Timer_t fps_ctrl;

	while (1) {
		Timer_start(&fps_ctrl);

		//出错时跳转到这里
		setjmp(abort_spot);

		//轮询事件
		poll_event();

		//执行命令缓存中的命令
		cmd_exec_buf();

		sv_frame();

		cl_frame();

		//刷新网络数据队列
		net_flush_quene();

		//控制FPS
		if (Timer_now(&fps_ctrl) < 1000/com_max_fps)
			SDL_Delay((1000/com_max_fps)-Timer_now(&fps_ctrl));
		com_real_fps = 1000/Timer_now(&fps_ctrl);

		//printf("fps:%d\n", com_real_fps);
	}

	return 0;
}

static void poll_event(void)
{
	static SDL_Event e;

	while (SDL_PollEvent(&e)) {
		switch(e.type)
		{
			case SDL_KEYDOWN:
				com_queue_event(EV_KEY, com_translate_key(&e.key.keysym), true);
				break;
			case SDL_KEYUP:
				com_queue_event(EV_KEY, com_translate_key(&e.key.keysym), false);
				break;

			case SDL_MOUSEMOTION:
				com_queue_event(EV_MOUSE_POS, e.motion.x, e.motion.y);
				com_queue_event(EV_MOUSE_REL, e.motion.xrel, e.motion.yrel);
				break;

			case SDL_MOUSEBUTTONDOWN:
			case SDL_MOUSEBUTTONUP: {
					unsigned char b;
					switch(e.button.button) {
						case 1:   b = K_MOUSE1;     break;
						case 2:   b = K_MOUSE3;     break;
						case 3:   b = K_MOUSE2;     break;
						case 4:   b = K_MWHEELUP;   break;
						case 5:   b = K_MWHEELDOWN; break;
						case 6:   b = K_MOUSE4;     break;
						case 7:   b = K_MOUSE5;     break;
						default:  b = K_AUX1 + ( e.button.button - 8 ) % 16; break;
					}
					com_queue_event(EV_KEY, b,
							(e.type == SDL_MOUSEBUTTONDOWN ? true : false));
				}
				break;

			case SDL_QUIT:
				com_quit(0);
				break;

			case SDL_ACTIVEEVENT:
				if (e.active.state & SDL_APPINPUTFOCUS) {
					printf("unactived\n");//窗口未激活
				}
				if (e.active.state & SDL_APPACTIVE) {
					printf("minimized\n");//最小化
				}
				break;

			default:
				break;
		}
	}
}

